home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
msysjour
/
vol07
/
04
/
netbios2
/
browser.c
< prev
next >
Wrap
Text File
|
1992-07-01
|
42KB
|
1,205 lines
/****************************************************************************
PROGRAM: BROWSER.C
PURPOSE: Demonstrates NetBIOS programming in Windows.
FUNCTIONS:
WinMain() - calls initialization function, processes message loop
InitApplication() - initializes window data and registers window
InitInstance() - saves instance handle and creates main window
MainWndProc() - processes messages
About() - processes messages for "About" dialog box
Connect() - presents dialog box for connecting to remote
server
Config() - presents dialog box for configuring locally
FillUpTheListBox()- a routine which calls remote versions of
dos_findfirst() and dos_findnext to fill
up the list box.
CopyName() - creates a blank padded name for NetBIOS purposes
datestr() - converts a date returned in struct find_t to a
string.
timestr() - converts a time returned in struct find_t to a
string
ListProc() - a procedure for handling list box messages
ErrorState() - a simple procedure for popping up an error message
CleanupClient() - NetBIOS related cleanup prior to ending program
HourGlass() - A procedure to change cursor to an hour glass
MessageLoop() - Processes incoming messages and basically
allows this program to yield control so that
other apps can run.
History:
January, 1992 Alok Sinha Created
****************************************************************************/
// Include Files
#include "windows.h"
#include "ncb.h"
#include "common.h"
#include "state.h"
#include "browser.h"
#include "netio.h"
#include <stdio.h>
#include <memory.h>
#include <string.h>
// Global variables and defines
HANDLE hInst; /* instance handle */
HWND hwndMain; /* handle to main window */
/* Remote Directory Name */
#define CURRENT_DIR "Current Working Directory at: "
char szRemoteDirectory[ NETBIOS_NAME_LENGTH+ _MAX_DIR + sizeof (CURRENT_DIR)];
char szDirectory[_MAX_DIR];
char chRemoteName [NETBIOS_NAME_LENGTH+1]; /* Local NetBIOS name */
char chLocalName [NETBIOS_NAME_LENGTH+1]; /* Remote NetBIOS name */
ClientFSM ClientState = C_UNINITIALIZED; /* Client State. See Client FSM*/
ServerFSM ServerState = S_UNINITIALIZED; /* Server State. See Server FSM*/
CallStatus enumCallStatus; /* Client Call Status */
SendStatus enumCSendStatus; /* Client Send Status */
SendStatus enumSSendStatus; /* Server Send Status */
ReceiveStatus enumCRecvStatus; /* Client Receive Status */
ReceiveStatus enumSRecvStatus; /* Server Receive Status */
char szErrorBuffer [ERROR_BUFFER_LENGTH]; /* Error Buffer */
BOOL fHourGlass = FALSE ; /* Hour Glass Cursor if TRUE */
BYTE bLsn = 0; /* Local Session Number */
BYTE bNameNum = 0; /* Name Number */
char szBaseWindowTitle[] = "Remote Browser";
char szWindowTitle[80];
// Functions
FARPROC lpfnOldList ;
VOID FillUpTheListBox(HWND hwndList);
VOID CopyName( char *pchLocalName, char *pchBuffer );
/****************************************************************************
FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
PURPOSE: calls initialization function, processes message loop
****************************************************************************/
MSG msg;
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
if (hPrevInstance)
return FALSE;
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
while ( TRUE )
{
if (MessageLoop ( (MSG FAR *) &msg))
{
break;
}
}
/*
* Any cleanup left remaining?
*/
// Stop the Client
if (ClientState != C_UNINITIALIZED)
CleanupClient();
// Stop the Server
if (ServerState != S_UNINITIALIZED)
DeleteServer();
// Return error to Windows
return (msg.wParam);
}
/****************************************************************************
FUNCTION: MessageLoop( MSG )
PURPOSE: Peeks at messages and thus allows yielding control.
RETURNS: TRUE if WM_QUIT has been received in the queue
FALSE otherwise.
****************************************************************************/
BOOL _loadds MessageLoop (MSG FAR * pmsgMSG)
{
if (PeekMessage(pmsgMSG, NULL, 0, 0, PM_REMOVE))
{
if (pmsgMSG->message==WM_QUIT)
{
return (TRUE);
}
TranslateMessage( pmsgMSG );
DispatchMessage ( pmsgMSG );
}
// Windows Idle time. At this time, some
// idle time activities can be accomplished
Server(hwndMain);
return (FALSE);
}
/****************************************************************************
FUNCTION: InitApplication(HANDLE)
PURPOSE: Initializes window data and registers window class
****************************************************************************/
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
WNDCLASS wc;
wc.style = CS_GLOBALCLASS;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "BrowserMenu";
wc.lpszClassName = "BrowserWClass";
return (RegisterClass(&wc));
}
/****************************************************************************
FUNCTION: InitInstance(HANDLE, int)
PURPOSE: Saves instance handle and creates main window
****************************************************************************/
BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance;
int nCmdShow;
{
hInst = hInstance;
hwndMain = CreateWindow(
"BrowserWClass",
szBaseWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (!hwndMain)
return (FALSE);
ShowWindow(hwndMain, nCmdShow);
UpdateWindow(hwndMain);
return (TRUE);
}
/****************************************************************************
FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages
MESSAGES:
WM_COMMAND - application menu
WM_COMMAND processing: (only special commands described)
IDM_OPEN - Get the NetBIOS name of remote "Server"
and create a NetBIOS session.
IDM_CONFIG- Get local NetBIOS name and start the
server.
IDM_EXIT - User wants to terminate application
IDM_ABOUT - display "About" box.
USER DEFINE COMMANDS
BW_CALL_BACK - message received when a NetBIOS 'CALL' command
completes. Calls are only posted by Client.
BW_LISTEN_BACK - message received when a NetBIOS 'LISTEN' command
completes. Listens are only posted by Server.
BW_C_RECEIVE_BACK - message received when a NetBIOS 'RECEIVE' command
posted by Client completes.
BW_S_RECEIVE_BACK - message received when a NetBIOS 'RECEIVE' command
posted by Server completes.
BW_C_SEND_BACK - message received when a NetBIOS 'SEND' command
posted by Client completes.
BW_S_SEND_BACK - message received when a NetBIOS 'SEND' command
posted by Server completes.
CLIENT_CONNECTED - message posted when a Listen completes
The message is posted by ListenCompleted()
routine in server.c
Notes:
****************************************************************************/
long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
FARPROC lpProc;
static HWND hwndList, hwndText ;
static RECT rect ;
HDC hDC ;
TEXTMETRIC tm ;
PNCB pncbNCB;
BYTE bRc ;
switch (message)
{
case WM_COMMAND:
switch (wParam)
{
case IDM_ABOUT: // Show the about box
lpProc = MakeProcInstance(About, hInst);
DialogBox(hInst, "AboutBox", hWnd, lpProc);
FreeProcInstance(lpProc);
break;
case IDM_CLOSE: // Close any current sessions/connections
if (ClientState>=C_CONNECTED)
{
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR)"Remote Browser" );
Hangup ( bLsn);
bLsn = 0;
ClientState = C_INITIALIZED;
DestroyWindow (hwndList);
DestroyWindow (hwndText);
}
break;
case IDM_OPEN: // Open a new session/connection with
// remote server.
if (ClientState< C_INITIALIZED)
{
ErrorState (hwndMain,
"Error! Use Config First"
);
}
else if (ClientState>= C_CONNECTED)
{
ErrorState (hwndMain,
"Error! Already Connected"
);
}
else
{ // Put up Connect Dialog box
lpProc = MakeProcInstance(Connect, hInst);
DialogBox(hInst, "Connect", hWnd, lpProc);
FreeProcInstance(lpProc);
// if state is not set to C_CALLING in Connect Dialog
// we are done
if ( ClientState != C_CALLING)
break;
// Tell the user we are connecting
// Don't want to display 'A' in 16th place. Hence, the
// NETBIOS_NAME_LENGTH -1 length restriction
sprintf(szErrorBuffer,
"Remote Browser - Connecting to [%*.*s]",
NETBIOS_NAME_LENGTH -1,
NETBIOS_NAME_LENGTH -1,
chRemoteName
);
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR) szErrorBuffer);
// Disable the menu
EnableMenuItem ( GetMenu(hwndMain), IDM_OPEN , MF_GRAYED);
EnableMenuItem ( GetMenu(hwndMain), IDM_CLOSE, MF_GRAYED);
EnableMenuItem ( GetMenu(hwndMain), IDM_CONFIG , MF_GRAYED);
// Now, make NetBIOS 'CALL' asynchronously
if ((bRc = Call(hwndMain,
(LPSTR)chLocalName,
(LPSTR)chRemoteName,
RECEIVE_NCB_RTO,
SEND_NCB_STO,
&bLsn
)) != NO_ERROR)
{ // Error in connecting to remote server
ClientState = C_INITIALIZED;
// Don't want to display 'A' in 16th place. Hence, the
// NETBIOS_NAME_LENGTH -1 length restriction
sprintf(szErrorBuffer,
"Error Creating Session with [%*.*s] Error [%x]",
NETBIOS_NAME_LENGTH -1,
NETBIOS_NAME_LENGTH -1,
chRemoteName,
bRc
);
MessageBox(hwndMain, (LPSTR)szErrorBuffer,
"Error", MB_OK);
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR) "Remote Browser" );
}
else // No Error in connecting to remote server
{
ClientState = C_CONNECTED;
// Don't want to display 'A' in 16th place. Hence, the
// NETBIOS_NAME_LENGTH -1 length restriction
sprintf(szErrorBuffer,
"Remote Browser - Connected to [%*.*s]",
NETBIOS_NAME_LENGTH - 1,
NETBIOS_NAME_LENGTH - 1,
chRemoteName
);
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR) szErrorBuffer );
}
// Enable menu items
EnableMenuItem ( GetMenu(hwndMain), IDM_OPEN , MF_ENABLED);
EnableMenuItem ( GetMenu(hwndMain), IDM_CLOSE, MF_ENABLED);
EnableMenuItem ( GetMenu(hwndMain), IDM_CONFIG , MF_ENABLED);
/* Create a List Box if session made*/
if ( ClientState==C_CONNECTED)
{
hDC = GetDC (hWnd) ;
GetTextMetrics (hDC, &tm) ;
ReleaseDC (hWnd, hDC) ;
rect.left = 20 * tm.tmAveCharWidth ;
rect.top = 3 * tm.tmHeight ;
// create a list box
hwndList = CreateWindow ("listbox", NULL,
WS_CHILDWINDOW |
WS_VISIBLE | LBS_STANDARD | LBS_USETABSTOPS,
tm.tmAveCharWidth,
tm.tmHeight * 3,
tm.tmAveCharWidth * MAX_LINE_SIZE +
GetSystemMetrics (SM_CXVSCROLL),
tm.tmHeight * 10,
hWnd,
1,
GetWindowWord (hWnd, GWW_HINSTANCE),
NULL
) ;
// Get remote current working directory
if ( R_getcwd (hwndMain, bLsn, szDirectory, _MAX_DIR) != NULL)
{
strcpy ( szRemoteDirectory, CURRENT_DIR);
strncat ( szRemoteDirectory, chRemoteName, NETBIOS_NAME_LENGTH - 1);
strcat ( szRemoteDirectory, szDirectory);
}
else // some error occured in remote getcwd()
strcpy (szRemoteDirectory, CURRENT_DIR);
// create a simple window showing current
// working directory at remote server site.
hwndText = CreateWindow ("static",
szRemoteDirectory,
WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
tm.tmAveCharWidth,
tm.tmHeight,
tm.tmAveCharWidth * MAXPATH,
tm.tmHeight,
hWnd,
2,
GetWindowWord (hWnd, GWW_HINSTANCE),
NULL
) ;
lpfnOldList = (FARPROC) GetWindowLong (hwndList, GWL_WNDPROC) ;
SetWindowLong ( hwndList,
GWL_WNDPROC,
(LONG) MakeProcInstance ((FARPROC) ListProc,
GetWindowWord (hWnd, GWW_HINSTANCE)
)
) ;
/* Fill up the list box with directory listing */
HourGlass(TRUE);
FillUpTheListBox(hwndList);
HourGlass(FALSE);
break ;
} /* if C_CONNECTED */
break;
} /* if ! C_INITIALIZED */
break;
case IDM_CONFIG: // User wants to configure local (client+server) machine
if (ClientState>= C_CONNECTED)
{
ErrorState (hwndMain,
"Error! Use Close to End Session First"
);
}
else if (ClientState==C_CALLING)
{
ErrorState (hwndMain,
"Error! Waiting to connect"
);
}
else // Client has not been initialized
{
/*
* Check the state of Server
*/
if (ServerState > S_LISTENING)
{
sprintf(szErrorBuffer,
"A remote user might be connected to you.\n %s",
"Do you want to cancel that connection?"
);
if (MessageBox(hwndMain, (LPSTR)szErrorBuffer,
"Warning", MB_YESNO) == IDNO)
break;
}
lpProc = MakeProcInstance(Config, hInst);
DialogBox(hInst, "Config", hWnd, lpProc);
FreeProcInstance(lpProc);
/*
* Initialize the Server, if Client got started
*/
if (ClientState == C_INITIALIZED)
{
InitServer(hwndMain);
sprintf(szErrorBuffer,
"Remote Browser - Local Name [%s]",
chLocalName
);
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR) szErrorBuffer );
}
} /* if ClientState >= C_CONNECTED */
break;
case IDM_EXIT: // user wants to stop application
// Stop the Client
CleanupClient();
ClientState = C_UNINITIALIZED;
// Stop the Server
DeleteServer();
ServerState = S_UNINITIALIZED;
PostQuitMessage(0);
break;
case LIST_PROCESSING:
// This is where future enhancements can be
// made change of directory or display
// a file content. See notes in ListProc()
MessageBox (hwndMain, "Not Implemented",
"Action undefined\n Place Holder for future enhancement",
MB_OK
);
break;
} // switch (wParam) upon WM_COMMAND
break;
case WM_SETFOCUS:
if (ClientState >= C_CONNECTED)
SetFocus (hwndList); // set focus on directory listing
break;
case WM_SETCURSOR: // Change cursor to hour glass
// if performing asynchronous
// activities
if ((wParam == hwndList) ||
(wParam == hwndMain))
{
if (fHourGlass) // Doing asynchronous activity
{
HourGlass (TRUE);
ShowCursor(TRUE);
SetActiveWindow(hWnd);
return (TRUE);
};
}
else
{
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZE:
rect.right = LOWORD (lParam) ;
rect.bottom = HIWORD (lParam) ;
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
case WM_DESTROY:
// Stop the Client
CleanupClient();
ClientState = C_UNINITIALIZED;
// Stop the Server
DeleteServer();
ServerState = S_UNINITIALIZED;
PostQuitMessage(0);
break;
/*
* User Defined messages are processed here
*/
case CLIENT_CONNECTED: // received when a client connected to server
// Don't want to display the 16th byte from chRemoteName
sprintf(szErrorBuffer,
"Remote Browser - [%*.*s] is Connected to us",
NETBIOS_NAME_LENGTH -1,
NETBIOS_NAME_LENGTH -1,
chRemoteName
);
SendMessage ( hwndMain, WM_SETTEXT, 0, (LONG) (LPSTR) szErrorBuffer );
break;
case BW_CALL_BACK: // received when a asynchronous 'CALL' completes
// sent by post routine in wnetbios.dll
// In this application, only Client end posts a 'CALL'
if (ClientState == C_CALLING)
{
// lparam should contain NCB pointer
pncbNCB = (PNCB) lParam;
if ((pncbNCB != NULL) && (pncbNCB->ncb_retcode == NRC_GOODRET))
{
enumCallStatus = CALL_CMPLT;
}
else
{
enumCallStatus = CALL_ERROR;
}
}
else
{
// We should never come here
ErrorState ( hwndMain,
"Error! unexpected BW_CALL_BACK received");
}
break;
case BW_C_SEND_BACK: // received when a asynchronous 'SEND'
// ,posted by Client, completes.
// sent by post routine in wnetbios.dll
if (ClientState == C_SENDING)
{
// lparam should contain NCB pointer
pncbNCB = (PNCB) lParam;
if ((pncbNCB != NULL) && (pncbNCB->ncb_retcode == NRC_GOODRET))
{
enumCSendStatus = SEND_CMPLT;
}
else
{
enumCSendStatus = SEND_ERROR;
}
}
else
{
// We should never come here
ErrorState( hwndMain,
"Error! unexpected BW_C_SEND_BACK received"
);
}
break;
case BW_S_SEND_BACK: // received when a asynchronous 'SEND'
// ,posted by Server, completes.
// sent by post routine in wnetbios.dll
if (ServerState == S_SENDING)
{
// lParam should contain NCB pointer
pncbNCB = (PNCB) lParam;
if ((pncbNCB != NULL) && (pncbNCB->ncb_retcode == NRC_GOODRET))
{
enumSSendStatus = SEND_CMPLT;
}
else
{
enumSSendStatus = SEND_ERROR;
}
}
else
{
// We should never come here
ErrorState( hwndMain,
"Error! unexpected BW_S_SEND_BACK received"
);
}
break;
case BW_C_RECEIVE_BACK: // received when a asynchronous 'RECEIVE'
// ,posted by Client, completes.
// sent by post routine in wnetbios.dll
if (ClientState == C_RECEIVING)
{
// lParam should contain NCB pointer
pncbNCB = (PNCB) lParam;
if ((pncbNCB != NULL) && (pncbNCB->ncb_retcode == NRC_GOODRET))
{
enumCRecvStatus = RECEIVE_CMPLT;
}
else
{
enumCRecvStatus = RECEIVE_ERROR;
}
}
else
{
// We should never come here
ErrorState( hwndMain,
"Error! unexpected BW_C_RECEIVE_BACK received"
);
}
break;
case BW_S_RECEIVE_BACK: // received when a asynchronous 'RECEIVE'
// ,posted by Server, completes.
// sent by post routine in wnetbios.dll
if (ServerState== S_RECEIVING)
{
ReceiveCompleted( hwndMain, (PNCB) lParam);
}
else
{
// We should never come here
ErrorState( hwndMain,
"Error! unexpected BW_S_RECEIVE_BACK received"
);
}
break;
case BW_LISTEN_BACK: // received when a asynchronous 'LISTEN' completes
// sent by post routine in wnetbios.dll
// In this application, only the Server posts a Listen
if (ServerState== S_LISTENING)
{
// Process the 'LISTEN' Completion
ListenCompleted( hwndMain, (PNCB) lParam);
}
else
{
// We should never come here
ErrorState( hwndMain,
"Error! unexpected BW_C_LISTEN_BACK received"
);
}
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
} // switch message
return (NULL);
}
/****************************************************************************
FUNCTION: About(HWND, unsigned, WORD, LONG)
PURPOSE: Processes messages for "About" dialog box
MESSAGES:
WM_INITDIALOG - initialize dialog box
WM_COMMAND - Input received
****************************************************************************/
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
switch (message) {
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if (wParam == IDOK
|| wParam == IDCANCEL) {
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
/****************************************************************************
FUNCTION: Connect(HWND, unsigned, WORD, LONG)
PURPOSE: Allows connection to remote computer by presenting a dialog box
MESSAGES:
WM_INITDIALOG - initialize dialog box
WM_COMMAND - Input received
****************************************************************************/
BOOL FAR PASCAL Connect(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
int iCount; /* Number of chars returned */
char chBuffer [ NETBIOS_NAME_LENGTH + 1 ];
switch (message)
{
case WM_INITDIALOG:
SendDlgItemMessage ( hDlg, IDD_RNAME, EM_LIMITTEXT, NETBIOS_NAME_LENGTH -1, 0L);
return (TRUE);
case WM_COMMAND:
switch (wParam)
{
case IDOK:
iCount = GetDlgItemText(hDlg,
IDD_RNAME,
chBuffer,
NETBIOS_NAME_LENGTH
);
if (iCount != 0)
{
/* Inform the user that we are tyring to
* establish a session
*/
// Prepare the name for remote server name
CopyName ( chRemoteName, chBuffer);
// Can't call yourself
if ( memcmp(chLocalName, chRemoteName, NETBIOS_NAME_LENGTH) == 0)
{
// Calling self not allowed
MessageBox(hwndMain, "Can not call yourself",
"Error", MB_OK);
}
else
{
// We are ready to call
chRemoteName[NETBIOS_NAME_LENGTH - 1] = SERVER_NAME_END;
ClientState = C_CALLING;
SetDlgItemText(hDlg, IDD_RNAME, "CONNECTING...");
}
} /* if (iCount != 0) */
EndDialog(hDlg, TRUE);
return (TRUE);
case IDCANCEL:
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
/****************************************************************************
FUNCTION: Config(HWND, unsigned, WORD, LONG)
PURPOSE: Gets local names and any other local configuration by presenting
a dialog box
MESSAGES:
WM_INITDIALOG - initialize dialog box
WM_COMMAND - Input received
****************************************************************************/
BOOL FAR PASCAL Config(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
int iCount; /* Number of chars returned */
BYTE bRc; /* Return Code */
char chBuffer [ NETBIOS_NAME_LENGTH + 1 ];
switch (message)
{
case WM_INITDIALOG:
SendDlgItemMessage ( hDlg, IDD_LNAME, EM_LIMITTEXT, NETBIOS_NAME_LENGTH -1, 0L);
return (TRUE);
case WM_COMMAND:
switch (wParam)
{
case IDOK:
iCount = GetDlgItemText(hDlg,
IDD_LNAME,
chBuffer,
NETBIOS_NAME_LENGTH
);
if (iCount != 0)
{
/* Inform the user that we are tyring to
* establish a session
*/
SetDlgItemText(hDlg, IDD_LNAME, "Configuring...");
/* First delete the name, if already exist
* then add the new name.
*/
HourGlass (TRUE);
(VOID) DeleteName( (LPSTR)chLocalName, bNameNum);
bNameNum = 0;
ClientState = C_UNINITIALIZED;
CopyName( chLocalName, chBuffer );
if ((bRc = AddName((LPSTR)chLocalName,
&bNameNum)) != NO_ERROR)
{
sprintf(szErrorBuffer,
"Error Adding Name [%s] Error [%x]",
chLocalName,
bRc
);
MessageBox(hwndMain, (LPSTR)szErrorBuffer,
"Error", MB_OK);
}
else
ClientState = C_INITIALIZED;
HourGlass(FALSE);
} /* if (iCount ! =0) */
EndDialog(hDlg, TRUE);
return (TRUE);
case IDCANCEL:
EndDialog(hDlg, TRUE);
return (TRUE);
} /* switch wParam */
break;
} /* switch message */
return (FALSE);
}
/****************************************************************************
FUNCTION: ListProc(HWND, unsigned, WORD, LONG)
PURPOSE: Processes List box
Processes:
WM_KEYDOWN - Do something upon selection
****************************************************************************/
long FAR PASCAL ListProc (hWnd, iMessage, wParam, lParam)
HWND hWnd ;
unsigned iMessage ;
WORD wParam ;
LONG lParam ;
{
short n = GetWindowWord (hWnd, GWW_ID) ;
// Currently we send a message to main window if it wishes to
// process the command.
// One can enhance the sample program.
// Suggested enhancements:
// if a directory is selected,
// show files in that (remote) directory by calling R_cwd()
// else if a file has been selected
// show contents of the file by calling
// R_open(), R_read(), and R_close() respectively
//
if (iMessage == WM_KEYDOWN && wParam == VK_RETURN)
SendMessage (GetParent (hWnd), WM_COMMAND, LIST_PROCESSING,
MAKELONG (hWnd, LBN_DBLCLK)) ;
// Call default list processing function
return CallWindowProc (lpfnOldList, hWnd, iMessage, wParam, lParam) ;
}
/****************************************************************************
FUNCTION: timestr
PURPOSE: Takes unsigned time in the format: fedcba9876543210
s=2 sec incr, m=0-59, h=23 hhhhhmmmmmmsssss
Changes to a 9-byte string (ignore seconds): hh:mm ?m
****************************************************************************/
char *timestr( unsigned t, char *buf )
{
int h = (t >> 11) & 0x1f, m = (t >> 5) & 0x3f;
sprintf( buf, "%2.2d:%02.2d %cm", h % 12, m, h > 11 ? 'p' : 'a' );
return buf;
}
/****************************************************************************
FUNCTION: datestr
PURPOSE: Takes unsigned date in the format: fedcba9876543210
d=1-31, m=1-12, y=0-119 (1980-2099) yyyyyyymmmmddddd
Changes to a 9-byte string: mm/dd/yy
****************************************************************************/
char *datestr( unsigned d, char *buf )
{
sprintf( buf, "%2.2d/%02.2d/%02.2d",
(d >> 5) & 0x0f, d & 0x1f, (d >> 9) + 80 );
return buf;
}
/****************************************************************************
FUNCTION: FillUpTheListBox()
PURPOSE: Fills up list box by calling the remote getfirst/getnext calls.
****************************************************************************/
VOID FillUpTheListBox(HWND hwndList)
{
struct find_t findFileInfo;
char chFileLine [ MAX_LINE_SIZE ],
chTimebuf[10],
chDatebuf[10];
BYTE bRc;
int j;
bRc = R_dos_findfirst ( hwndMain,
bLsn,
"*.*", // File Name
_A_ARCH | _A_HIDDEN | _A_NORMAL | _A_RDONLY|
_A_SUBDIR, // File Type
&findFileInfo); // File Details
if (bRc == NO_ERROR)
{
do
{
// Need to handle directories specially
if (findFileInfo.attrib & _A_SUBDIR)
{
j = sprintf(chFileLine, "%s",
findFileInfo.name
);
j += sprintf(chFileLine + j, "\t\t<DIR>");
}
else
j = sprintf(chFileLine, "%-12s\t%-8ld",
findFileInfo.name,
findFileInfo.size
);
sprintf(chFileLine + j,
"\t%-9s\t%-9s",
timestr( findFileInfo.wr_time, chTimebuf),
datestr( findFileInfo.wr_date, chDatebuf )
);
SendMessage ( hwndList, LB_ADDSTRING, -1 , (LONG) (LPSTR) chFileLine);
}while ( R_dos_findnext ( hwndMain, bLsn, &findFileInfo) == NO_ERROR);
}
return;
}
/****************************************************************************
FUNCTION: CleanupClient()
PURPOSE: End any session, if exists and remove local name.
****************************************************************************/
VOID CleanupClient(VOID)
{
HourGlass(TRUE);
/* Disconnect Local Session with remote Server */
if (bLsn)
{
Hangup( bLsn);
bLsn = 0;
}
/* Remove Local name from Name Table */
if (bNameNum)
{
DeleteName( (LPSTR)chLocalName, bNameNum);
bNameNum = 0;
}
HourGlass(FALSE);
}
/****************************************************************************
FUNCTION: HourGlass()
PURPOSE: Coverts the cursor from normal arrow to Hour Glass type.
****************************************************************************/
VOID HourGlass ( BOOL fShowHourGlass)
{
POINT pt; /* Location of the hour glass */
if (fShowHourGlass) // Caller wants to display hour glass
{
fHourGlass = TRUE;
SetCursor( LoadCursor(NULL, IDC_WAIT));
GetCursorPos ( (LPPOINT) &pt);
SetCursorPos ( pt.x, pt.y);
}
else // Caller does not want to display hour glass
{
fHourGlass = FALSE;
SetCursor ( LoadCursor(NULL, IDC_ARROW));
}
}
/****************************************************************************
FUNCTION: CopyName()
PURPOSE: Copies a name into pchLocalName from pchBuffer and pads
the name with blanks (0x20). This is necessary
for NetBIOS compliance.
****************************************************************************/
VOID CopyName( char *pchLocalName, char *pchBuffer )
{
size_t i;
// Copy the characters first
for ( i =0; i < strlen(pchBuffer) && i < NETBIOS_NAME_LENGTH; i++)
pchLocalName [i] = pchBuffer [i];
// Now blank pad it
for ( ; i < NETBIOS_NAME_LENGTH; i++)
pchLocalName [i] = 0x20;
// put '\0' after 16th byte for sprintf to work correctly
pchLocalName [ NETBIOS_NAME_LENGTH ] = '\0';
}
/****************************************************************************
FUNCTION: ErrorState
PURPOSE: A simple routine which takes a handle (hwnd) to a window and a
string (lpError). It then displays the string using
MessageBox()
****************************************************************************/
VOID ErrorState (HWND hwnd, LPSTR lpError)
{
sprintf(szErrorBuffer, "%s", lpError);
MessageBox(hwnd, (LPSTR)szErrorBuffer, "Error", MB_OK);
}